#pragma once

#include <compl.h>
#include <ddblk/adep_dblk.h>
/* 定义依赖wait策略 */
OU2INFUN(blkwait, nlock_wait)

/* 分配策略 */
OU2INFUN(lknode, nlock_lknode)

/* NLOCK的等待不能放弃，否则可能出现死锁，因此不提供timed接口 */

/* 节点锁需要依赖一个节点的分配器? -应当解耦合, 但是应该内部解耦合而不是外部 */
#define DECL_NLOCK(locktype)	\
SAI _##locktype##lock_t *_##locktype##_init(void *ptr, size_t size, INFUN(nlock_lknode, lknode));\
SAI void *_##locktype##_destruct(_##locktype##lock_t *s, INFUN(nlock_lknode, lknode));\
SAI bool_t _##locktype##_lock(_##locktype##lock_t *s, locktoken_t *ptoken, waitcnt_t cnt, \
	INFUN(nlock_wait, waitpolicy), INFUN(nlock_lknode, lknode), const acq_ord_t order);\
SAI bool_t _##locktype##_unlock(_##locktype##lock_t *s, locktoken_t token, waitcnt_t cnt, \
	INFUN(nlock_wait, waitpolicy), INFUN(nlock_lknode, lknode),  const rel_ord_t order);\

/* 填充内容(锁等待策略, 锁内存序) */
/* 定义lock 不需要考虑, token */
#define DEF_NLOCK(locktype, name, pwaitpolicy, plknodemgr)	\
typedef _##locktype##lock_t name##lock_t;		\
typedef _##locktype##node_t name##node_t;		\
SAI lock_t *name##_init(void *ptr, size_t size){ return (lock_t *)_##locktype##_init(ptr, size, plknodemgr); }\
SAI void *name##_destruct(lock_t *s){ return _##locktype##_destruct((name##lock_t *)s, plknodemgr); }\
SAI bool_t name##_lock(lock_t *l, locktoken_t *ptoken){ return _##locktype##_lock((name##lock_t *)l, ptoken, -1, pwaitpolicy, plknodemgr, LACQ); }\
SAI bool_t name##_unlock(lock_t *l, locktoken_t token){ return _##locktype##_unlock((name##lock_t *)l, token, -1, pwaitpolicy, plknodemgr, RREL); }\
SAI bool_t name##_lock_relax(lock_t *l, locktoken_t *ptoken){ return _##locktype##_lock((name##lock_t *)l, ptoken, -1, pwaitpolicy, plknodemgr, LRLX); }\
SAI bool_t name##_unlock_relax(lock_t *l, locktoken_t token){ return _##locktype##_unlock((name##lock_t *)l, token, -1, pwaitpolicy, plknodemgr, RRLX); }\
MAY_UNUSED NEW_OUFUN(lock, name, name##_init, name##_destruct, name##_lock, name##_unlock, name##_lock_relax, name##_unlock_relax)
